package iamutkarshtiwari.github.io.ananas.editimage.view;

import iamutkarshtiwari.github.io.ananas.editimage.utils.PaintUtil;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.PixelMapHolder;
import ohos.agp.utils.Matrix;
import ohos.agp.utils.Point;
import ohos.agp.utils.Rect;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;
import ohos.media.image.PixelMap;
import ohos.media.image.common.ImageInfo;

public class RotateImageView extends Component implements Component.EstimateSizeListener, Component.DrawTask {

    private RectFloat srcRect;
    private RectFloat dstRect;
    private Rect maxRect;

    private PixelMap bitmap;
    private Matrix matrix = new Matrix();

    private float scale;
    private float rotateAngle;

    private RectFloat wrapRect = new RectFloat();
    private Paint bottomPaint;
    private RectFloat originImageRect;

    /**
     * 构造
     *
     * @param context Context对象
     */
    public RotateImageView(Context context) {
        super(context);
        init(context);
    }

    /**
     * 构造
     *
     * @param context Context对象
     * @param attrSet AttrSet对象
     */
    public RotateImageView(Context context, AttrSet attrSet) {
        super(context, attrSet);
        init(context);
    }

    private void init(Context context) {
        srcRect = new RectFloat();
        dstRect = new RectFloat();
        maxRect = new Rect();
        bottomPaint = PaintUtil.newRotateBottomImagePaint();
        originImageRect = new RectFloat();

        addDrawTask(this);
        setEstimateSizeListener(this);
    }

    /**
     * 添加图像
     *
     * @param bit       图像
     * @param imageRect 图像对应的Rect
     */
    public void addBit(PixelMap bit, RectFloat imageRect) {
//        PixelMap.InitializationOptions options = new PixelMap.InitializationOptions();
//        options.pixelFormat = PixelFormat.ARGB_8888;
        bitmap = bit;//PixelMap.create(bit, options); //
//        srcRect.set(0, 0, bitmap.getWidth(), bitmap.getHeight());
        ImageInfo srcInfo = bitmap.getImageInfo();
        srcRect.modify(0, 0, srcInfo.size.width, srcInfo.size.height);
        dstRect = imageRect;

//        originImageRect.set(0, 0, bit.getWidth(), bit.getHeight());
        ImageInfo bitInfo = bit.getImageInfo();
        originImageRect.modify(0, 0, bitInfo.size.width, bitInfo.size.height);
        invalidate();
    }

    /**
     * 图像旋转
     *
     * @param angle 角度
     */
    public void rotateImage(float angle) {
        rotateAngle = angle;
        invalidate();
    }

    /**
     * 重置
     */
    public void reset() {
        rotateAngle = 0;
        scale = 1;
        invalidate();
    }

    @Override
    public boolean onEstimateSize(int widthMeasureSpec, int heightMeasureSpec) {
//        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = EstimateSpec.getSize(widthMeasureSpec);
        int height = EstimateSpec.getSize(heightMeasureSpec);

        setEstimatedSize(
                EstimateSpec.getChildSizeWithMode(width, width, EstimateSpec.NOT_EXCEED),
                EstimateSpec.getChildSizeWithMode(height, height, EstimateSpec.NOT_EXCEED)
        );
        return true;
    }

    @Override
    public void addDrawTask(DrawTask task) {
        super.addDrawTask(task);
        task.onDraw(this, mCanvasForTaskOverContent);
    }

    @Override
    //draw
    public void onDraw(Component component, Canvas canvas) {
//        super.draw(canvas);
        if (bitmap == null)
            return;
        maxRect.set(0, 0, getWidth(), getHeight());

        calculateWrapBox();
        scale = 1;
        if (wrapRect.getWidth() > getWidth()) {
            scale = getWidth() / wrapRect.getWidth();
        }

        canvas.save();

//        canvas.scale(scale, scale, canvas.getWidth() >> 1,
//                canvas.getHeight() >> 1);
        canvas.scale(scale, scale, getWidth() >> 1, getHeight() >> 1);
        canvas.drawRect(wrapRect, bottomPaint);
//        canvas.rotate(rotateAngle, canvas.getWidth() >> 1,
//                canvas.getHeight() >> 1);
        canvas.rotate(rotateAngle, getWidth() >> 1, getHeight() >> 1);

//        canvas.drawBitmap(bitmap, srcRect, dstRect, null);
        canvas.drawPixelMapHolderRect(new PixelMapHolder(bitmap), srcRect, dstRect, new Paint());
        canvas.restore();
    }

    private void calculateWrapBox() {
//        wrapRect.set(dstRect);
        wrapRect.modify(dstRect);
        matrix.reset();// 重置矩阵为单位矩阵

        int centerX = getWidth() >> 1;  //getWidth() >> 1;
        int centerY = getHeight() >> 1; //getHeight() >> 1;

        matrix.postRotate(rotateAngle, centerX, centerY);
        matrix.mapRect(wrapRect);
    }

    /**
     * 获取新的Rect
     *
     * @return Rect
     */
    public RectFloat getImageNewRect() {
        Matrix matrix = new Matrix();
//        m.postRotate(this.rotateAngle, originImageRect.centerX(),
//                originImageRect.centerY());
        Point center = originImageRect.getCenter();
        matrix.postRotate(this.rotateAngle, center.getPointX(),
                center.getPointY());
        matrix.mapRect(originImageRect);
        return originImageRect;
    }

    /**
     * 获取图像缩放比
     *
     * @return 缩放
     */
    //getScale
    public synchronized float getScale1() {
        return scale;
    }

    /**
     * 获取图像旋转角度
     *
     * @return 角度
     */
    public synchronized float getRotateAngle() {
        return rotateAngle;
    }
}
